#include "stdafx.h"
#include "SessionMessage.h"
#include <Tlhelp32.h>

struct SessionFindData {
	DWORD pid;
	BOOL bFound;
	HWND hWnd;
};


static BOOL CALLBACK enum_wnd_cb(HWND hWnd, LPARAM lParam) {
	SessionFindData *args = (SessionFindData*)lParam;

	DWORD pid;
	::GetWindowThreadProcessId(hWnd, &pid);

	if (pid == args->pid) {
		args->bFound = TRUE;
		args->hWnd = hWnd;
		return FALSE;
	}
	return TRUE;
}
static BOOL CALLBACK enum_desktop_cb(LPSTR lpszDesktop, LPARAM lParam) {
	HDESK desk = ::OpenDesktopA(lpszDesktop, 0, FALSE, DESKTOP_ENUMERATE);
	if (desk) {
		SessionFindData *args = (SessionFindData*)lParam;
		::EnumDesktopWindows(desk, enum_wnd_cb, lParam);
		::CloseDesktop(desk);
		if (args->bFound)
			return FALSE;
	}
	return TRUE;
}
static BOOL CALLBACK enum_winsta_cb(LPSTR lpszWindowStation, LPARAM lParam) {
	HWINSTA winsta = ::OpenWindowStationA(lpszWindowStation,
		FALSE, WINSTA_ENUMERATE | WINSTA_ENUMDESKTOPS);
	if (winsta) {
		SessionFindData *args = (SessionFindData*)lParam;
		::EnumDesktopsA(winsta, enum_desktop_cb, lParam);
		::CloseWindowStation(winsta);
		if (args->bFound)
			return FALSE;
	}
	return TRUE;
}

LRESULT SessionSendMessage(
	__in DWORD pid,
	__in UINT uMsg,
	__in WPARAM wParam,
	__in LPARAM lParam) {
	HWND hWnd = SessionFindWindow(pid);
	return ::SendMessage(hWnd, uMsg, wParam, lParam);
}

BOOL SessionPostMessage(
	__in DWORD pid,
	__in UINT uMsg,
	__in WPARAM wParam,
	__in LPARAM lParam) {
	HWND hWnd = SessionFindWindow(pid);
	return ::PostMessage(hWnd, uMsg, wParam, lParam);
}

HWND SessionFindWindow(
	__in DWORD pid) {
	SessionFindData args = { 0 };
	args.bFound = FALSE;
	args.hWnd = 0;
	args.pid = pid;
	::EnumWindowStationsA(enum_winsta_cb, (LPARAM)&args);
	return args.hWnd;
}

BOOL GetPidByProcessName(LPCTSTR pProcess, DWORD*dwPid, BOOL bSkipCur) {
	HANDLE hSnapshot;
	PROCESSENTRY32 lppe;
	hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

	if (hSnapshot == NULL)
		return FALSE;

	lppe.dwSize = sizeof(lppe);

	if (!::Process32First(hSnapshot, &lppe))
		return FALSE;
	do {
		if (_tcscmp(lppe.szExeFile, pProcess) == 0) {
			if (bSkipCur && lppe.th32ProcessID == ::GetCurrentProcessId()) {
				continue;
			}
			*dwPid = lppe.th32ProcessID;
		}
	} while (::Process32Next(hSnapshot, &lppe));

	return TRUE;
}